package cn.lili.controller.feign;

import cn.hutool.core.collection.CollectionUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.cache.LockPrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.enums.SwitchEnum;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.utils.SnowFlake;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.PageVO;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.constant.CommonConstant;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.entity.dos.*;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.dto.ProxyGoodsOperationDTO;
import cn.lili.modules.goods.entity.enums.*;
import cn.lili.modules.goods.entity.vos.GoodsVO;
import cn.lili.modules.goods.integration.GoodsIntegrationService;
import cn.lili.modules.goods.service.GoodsGalleryService;
import cn.lili.modules.goods.service.GoodsService;
import cn.lili.modules.goods.service.GoodsSkuService;
import cn.lili.modules.goods.service.WholesaleService;
import cn.lili.modules.grab.haiguan.service.impl.FreeWarehouseImpl;
import cn.lili.modules.operationcenter.entity.vos.UrbanStationSearchParams;
import cn.lili.modules.goods.service.*;
import cn.lili.modules.grab.haiguan.service.IFreeWarehouse;
import cn.lili.modules.order.order.client.OrderClient;
import cn.lili.modules.order.order.client.OrderFreeStatusLogClient;
import cn.lili.modules.order.order.entity.constant.FreeWarehouseConstant;
import cn.lili.modules.order.order.entity.dos.Order;
import cn.lili.modules.order.order.entity.dos.OrderFreeStatusLog;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.dto.OrderSearchParams;
import cn.lili.modules.order.order.entity.enums.OrderStatusEnum;
import cn.lili.modules.order.order.entity.vo.GoodsSkuMap;
import cn.lili.modules.order.order.entity.vo.warehouse.InterceptReq;
import cn.lili.modules.order.order.entity.vo.warehouse.ShopSalesOrderReq;
import cn.lili.modules.order.order.entity.vo.warehouse.ShopSalesOrderRes;
import cn.lili.modules.order.order.entity.vo.warehouse.customs.UploadCEBMessageRequest;
import cn.lili.modules.promotion.entity.vos.BoxMhgoodsVO;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.search.entity.dto.EsGoodsSearchDTO;
import cn.lili.modules.search.service.EsGoodsSearchService;
import cn.lili.modules.store.client.FreightTemplateClient;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.entity.vos.FreightTemplateVO;
import cn.lili.modules.supplier.entity.dto.SupplierGoodsOperationDTO;
import cn.lili.modules.system.client.LogisticsClient;
import cn.lili.modules.system.entity.dos.Logistics;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.mybatis.util.SceneHelp;
import com.alibaba.fastjson.JSONObject;
import cn.lili.routing.GoodsRoutingKey;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 商品分类 feign client
 *
 * @author Chopper
 * @version v1.0
 * 2021-12-07 06:08
 */
@RestController
@RequiredArgsConstructor
@Slf4j
public class GoodsFeignController implements GoodsClient {


    private final GoodsService goodsService;

    private final GoodsSkuService goodsSkuService;

    private final GoodsIntegrationService goodsIntegrationService;

    private final GoodsGalleryService goodsGalleryService;

    private final WholesaleService wholesaleService;

    private final FreightTemplateClient freightTemplateClient;

    private final ApplicationEventPublisher applicationEventPublisher;

    private final AmqpExchangeProperties amqpExchangeProperties;

    private final Cache cache;

    private final EsGoodsSearchService goodsSearchService;

    private final IFreeWarehouse freeWarehouse;

    private final OrderClient orderClient;

    private final LogisticsClient logisticsClient;

    private final FreeOrderLogService freeOrderLogService;

    private final OrderFreeStatusLogClient orderFreeStatusLogClient;

    private final RedissonClient redisson;

    @Override
    public void addSupplierGoods(SupplierGoodsOperationDTO supplierGoodsOperationDTO) {
        goodsIntegrationService.saveSupplierGoods(supplierGoodsOperationDTO);
    }

    @Override
    public void editSupplierGoods(SupplierGoodsOperationDTO supplierGoodsOperationDTO) {
        goodsIntegrationService.updateSupplierGoods(
                supplierGoodsOperationDTO);
    }

    @Override
    public void editSupplierGoodsCategory(SupplierGoodsOperationDTO supplierGoodsOperationDTO) {
        goodsIntegrationService.updateSupplierGoodsCategory(supplierGoodsOperationDTO.getGoodsIds(),
                supplierGoodsOperationDTO.getCategoryPathIds());
    }

    @Override
    public void addSupplierCategoryPathSon(String ids, String categoryPathSon, String categoryPathSonName) {
        goodsIntegrationService.addSupplierCategoryPathSon(ids, categoryPathSon, categoryPathSonName);
    }

    @Override
    public Page<Goods> queryByParams(GoodsSearchParams goodsSearchParams) {
        return goodsService.page(PageUtil.initPage(goodsSearchParams), goodsSearchParams.queryWrapper());
    }

    /**
     * 查询商品VO
     *
     * @param goodsId 商品id
     * @return 商品VO
     */
    @Override
    public GoodsVO getGoodsVO(String goodsId) {
        return goodsIntegrationService.getGoodsVO(goodsId);
    }

    @Override
    public List<GoodsGallery> getGoodsGallery(String goodsId) {
        return goodsGalleryService.goodsGalleryList(goodsId);
    }

    @Override
    public void updateGoodsGallery(List<GoodsGallery> goodsGalleryList) {
        for(GoodsGallery goodsGallery : goodsGalleryList){
            goodsGalleryService.updateById(goodsGallery);
        }
    }

    @Override
    public void updateGoodsInfoImages(Goods goods) {
        goodsService.updateGoodsIntro(goods);
    }

    @Override
    public void updateGoodsSkuImages(List<GoodsSku> skuList) {
        goodsSkuService.updateImages(skuList);
    }

    @Override
    public void updateVideoById(Goods goods) {
        LambdaUpdateWrapper<Goods> goodsLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        goodsLambdaUpdateWrapper.eq(Goods::getId, goods.getId());
        goodsLambdaUpdateWrapper.set(Goods::getGoodsVideo, goods.getGoodsVideo());
        goodsService.update(goodsLambdaUpdateWrapper);
    }

    @Override
    public GoodsSku getGoodsSkuByIdFromCache(String skuId) {
        return goodsSkuService.getGoodsSkuByIdFromCache(skuId);
    }


    @Override
    public GoodsSku getCanPromotionGoodsSkuByIdFromCache(String skuId) {
        GoodsSku goodsSku = goodsSkuService.getGoodsSkuByIdFromCache(skuId);
        if (goodsSku != null && SalesModeEnum.WHOLESALE.name().equals(goodsSku.getSalesModel())) {
            throw new ServiceException(ResultCode.PROMOTION_GOODS_DO_NOT_JOIN_WHOLESALE, goodsSku.getGoodsName());
        }
        return goodsSku;
    }

    @Override
    public void updateStoreDetail(Store store) {
        goodsIntegrationService.updateStoreDetail(store);
    }

    @Override
    public void underStoreGoods(String id) {
        goodsIntegrationService.underStoreGoods(id);
    }

    @Override
    public Long count(String storeId) {
        return goodsService.countStoreGoodsNum(storeId);
    }

    @Override
    public Integer getStock(String skuId) {
        return goodsSkuService.getStock(skuId);
    }

    /**
     * 添加商品评价数量
     *
     * @param commentNum 评价数量
     * @param goodsId    商品ID
     */
    @Override
    public void addGoodsCommentNum(Integer commentNum, String goodsId) {
        goodsService.addGoodsCommentNum(commentNum, goodsId);
    }

    @Override
    public Goods getById(String goodsId) {
        return goodsService.getById(goodsId);
    }


    @Override
    public List<Goods> queryListByParams(GoodsSearchParams searchParams) {
        return goodsService.queryListByParams(searchParams);
    }


    @Override
    public List<String> getSkuIdsByGoodsId(String goodsId) {
        return goodsSkuService.getSkuIdsByGoodsId(goodsId);
    }


    @Override
    public List<GoodsSku> getGoodsSkuByList(GoodsSearchParams searchParams) {
        return goodsSkuService.getGoodsSkuByList(searchParams);
    }

    @Override
    public void updateGoodsBuyCount(String goodsId, int buyCount) {
        goodsService.updateGoodsBuyCount(goodsId, buyCount);
    }

    @Override
    public GoodsSku getGoodsSkuById(String goodsId) {
        return goodsSkuService.getById(goodsId);
    }

    @Override
    public void updateGoodsSku(GoodsSku goodsSku) {
        goodsSkuService.update(goodsSku);
    }

    @Override
    public Goods getGoodsByParams(GoodsSearchParams searchParams) {
        return goodsService.getGoodsByParams(searchParams);
    }

    @Override
    public Wholesale getMatchWholesale(String goodsId, Integer num) {
        return wholesaleService.match(goodsId, num);
    }

    @Override
    public List<Wholesale> getWholesale(String goodsId) {
        return wholesaleService.findByGoodsId(goodsId);
    }

    @Override
    public Long countSkuNum(String storeId) {
        return goodsSkuService.countSkuNum(storeId);
    }

    @Override
    public Long countSkuNumByGoods(String storeId) {
        return goodsService.countSkuNumByGoods(storeId);
    }

    @Override
    public void deleteGoods(List<String> goodsIds) {
        goodsIntegrationService.deleteGoods(goodsIds, null);
    }

    @Override
    public void deleteGoodsV2(List<String> goodsIds) {
        goodsIntegrationService.deleteGoodsV2(goodsIds,null);
    }

    @Override
    @Transactional
    public void addSupplierGoods(String goodsId) {
        Goods goods = goodsService.getById(goodsId);
        //商品为空
        if (goods == null) {
            throw new ServiceException(ResultCode.GOODS_NOT_EXIST);
        }

        //一个店铺只能对一个商品代理一次
        LambdaQueryWrapper<Goods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Goods::getSupplierGoodsId, goodsId);
        queryWrapper.eq(Goods::getDeleteFlag, false);
        queryWrapper.eq(Goods::getStoreId, Objects.requireNonNull(UserContext.getCurrentUser()).getExtendId());


        if (this.goodsService.count(queryWrapper) > 0) {
            throw new ServiceException(ResultCode.GOODS_PROXY_TOO_MUCH);
        }
        List<GoodsSku> goodsSkuList = goodsSkuService.getGoodsSkuListByGoodsId(goodsId);
        storeOwnHandler(goods);

        List<FreightTemplateVO> freightTemplateList = freightTemplateClient.getFreightTemplateList(goods.getStoreId());

        // 如果没有运费模板或者商品类型为虚拟商品，则模板id为-1(无运费)
        if (freightTemplateList.isEmpty() || goods.getGoodsType().equals(GoodsTypeEnum.VIRTUAL_GOODS.name())) {
            goods.setTemplateId("-1");
        } else {
            goods.setTemplateId(freightTemplateList.get(0).getId());
        }

        //处理sku信息
        List<GoodsSku> goodsSkus = storeOwnHandler(goodsSkuList, goods);

        goodsService.save(goods);
        goodsSkuService.saveBatch(goodsSkus);
    }

    @Override
    public void syncStock(List<String> goodsId) {
        goodsId.forEach(goodsService::syncStock);
    }

    @Override
    public void generateFullEs(Integer isGreenGoods) {
        goodsIntegrationService.generateFullEs(isGreenGoods);
    }

    @Override
    public void editProxyGoods(ProxyGoodsOperationDTO proxyGoodsOperationDTO) {
        goodsIntegrationService.editProxyGoods(proxyGoodsOperationDTO);
    }

    /**
     * 格式化商品为店铺所有
     *
     * @param goods 商品
     */
    private void storeOwnHandler(Goods goods) {

        String supplierGoodsId = goods.getId();
        String supplierId = goods.getStoreId();
        String supplierName = goods.getStoreName();

        AuthUser authUser = UserContext.getCurrentUser();
        //格式化商品为店铺所有，需要将商品id置空，以及配置店铺id和店铺名称
        goods.setId(SnowFlake.getIdStr());
        goods.setStoreId(authUser.getExtendId());
        goods.setMarketEnable(GoodsMarketEnum.DOWN.name());
        goods.setStoreName(authUser.getExtendName());

        goods.setSupplierGoodsId(supplierGoodsId);
        goods.setSupplierId(supplierId);
        goods.setSupplierName(supplierName);
        goods.setSupplierEnum(
                SupplierEnum.getSupplierEnum(supplierId).name()
        );
        goods.setSupportProxy(false);
        goods.setSupportPurchase(false);
        goods.setSalesModel(SalesModeEnum.RETAIL.name());
        goods.setIsProxyGoods(true);

        // 写入当前用户场景
        SceneHelp.objectHandler(goods);

        //复制商品相册
        goodsGalleryService.copyGoodsGallery(supplierGoodsId, goods.getId());

    }

    /**
     * 格式化SKU为供应商所有
     *
     * @param goodsSkus 商品sku
     */
    private List<GoodsSku> storeOwnHandler(List<GoodsSku> goodsSkus, Goods goods) {
        AuthUser authUser = UserContext.getCurrentUser();

        //接收sku集合
        List<GoodsSku> result = new ArrayList<>();
        Double minPrice = null;
        //格式化商品为店铺所有，需要将商品id置空，以及配置店铺id和店铺名称
        for (GoodsSku goodsSku : goodsSkus) {
            try {
                GoodsSku sku = goodsSku.clone();

                String supplierGoodsId = goodsSku.getGoodsId();
                String supplierSkuId = goodsSku.getId();
                String supplierId = goodsSku.getStoreId();
                String supplierName = goodsSku.getStoreName();

                sku.setId(null);
                sku.setGoodsId(goods.getId());
                sku.setStoreId(authUser.getExtendId());
                sku.setStoreName(authUser.getExtendName());
                sku.setMarketEnable(GoodsMarketEnum.DOWN.name());

                sku.setSupplierGoodsId(supplierGoodsId);
                sku.setSupplierSkuId(supplierSkuId);
                sku.setSupplierId(supplierId);
                sku.setSupplierName(supplierName);

                sku.setSupportProxy(false);
                sku.setSupportPurchase(false);
                sku.setSalesModel(SalesModeEnum.RETAIL.name());
                sku.setIsProxyGoods(true);
                sku.setFreightTemplateId(goods.getTemplateId());

                //默认代理商的价格为当前商品的价格的1.1倍
                sku.setVipPrice(goodsSku.getVipPrice());
                sku.setFyVipPrice(goodsSku.getFyVipPrice());
                sku.setCost(goodsSku.getPrice());
                //默认代理商的价格为当前商品的价格的1.15倍
                BigDecimal price = BigDecimal.valueOf(goodsSku.getRetailPrice() != null ? goodsSku.getRetailPrice() : Double.MAX_VALUE);
                if (goodsSku.getRetailPrice() == null || goodsSku.getRetailPrice().equals(0D)) {
                    price = BigDecimal.valueOf(goodsSku.getPrice()).multiply(BigDecimal.valueOf(1.15)).setScale(2, RoundingMode.HALF_UP);
                }
                sku.setPrice(price.doubleValue());

                result.add(sku);
            } catch (CloneNotSupportedException e) {
                throw new RuntimeException(e);
            }
        }

        goods.setPrice(minPrice);
        result.forEach(SceneHelp::objectHandler);
        return result;
    }

    @Override
    public boolean updateGoods(Goods goods) {
        if (StringUtils.isEmpty(goods.getThirdPartyPlatformId())) {
            log.error("updateGoods  ==>  thirdPartyPlatformId为空");
            return false;
        }
        LambdaUpdateWrapper<Goods> goodsLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        goodsLambdaUpdateWrapper.eq(Goods::getThirdPartyPlatformId, goods.getThirdPartyPlatformId());
        goodsLambdaUpdateWrapper.eq(Goods::getDeleteFlag, Boolean.FALSE);
        if (StringUtils.isNotEmpty(goods.getMarketEnable())) {
            goodsLambdaUpdateWrapper.set(Goods::getMarketEnable, goods.getMarketEnable());
        }
        if (StringUtils.isNotEmpty(goods.getAuthFlag())) {
            goodsLambdaUpdateWrapper.set(Goods::getAuthFlag, goods.getAuthFlag());
        }
        goodsService.update(goodsLambdaUpdateWrapper);
        return true;
    }


    @Override
    public List<Goods> getByThirdPartyPlatformId(String productId) {
        if (StringUtils.isEmpty(productId)) {
            log.error("productId ==== 为空");
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Goods> goodsLambdaQueryWrapper = new LambdaQueryWrapper<>();
        goodsLambdaQueryWrapper.eq(Goods::getThirdPartyPlatformId, productId);
        goodsLambdaQueryWrapper.eq(Goods::getDeleteFlag, Boolean.FALSE);
        return goodsService.list(goodsLambdaQueryWrapper);
    }

    @Override
    public String getToken() {
        return goodsService.getToken();
    }

    @Override
    public List<Goods> getProxyGoodsList(String supplierId, String supplierGoodsId) {
        log.info("=================获取代理商品列表===");
        return goodsIntegrationService.getProxyGoodsList(supplierId,supplierGoodsId);
    }

//    public List<JSONObject> getPlatformGoodsList() {
//        return goodsService.getPlatformGoodsList(Goods);
//    }


    @Override
    public Map<String, List> goodsSkusConversion(GoodsSkuMap goodsSkuMap) {
        log.info("jsonObjects == {}" ,JSONObject.toJSONString(goodsSkuMap.getPlatformGoodsDetail()));
        log.info("goodsList == {}" ,JSONObject.toJSONString(goodsSkuMap.getGoodsList()));
        return goodsService.goodsSkusConversion(goodsSkuMap.getPlatformGoodsDetail(), goodsSkuMap.getGoodsList());
    }

    @Override
    public List<JSONObject> getPlatformGoodsDetail(List<String> goodsIds) {
        return goodsService.getPlatformGoodsDetail(goodsIds.stream().map(Integer::valueOf).collect(Collectors.toList()));
    }

    @Override
    public boolean updateById(Goods goods) {
        return goodsService.updateById(goods);
    }
    @Override
    public void addStorage(Integer id) {
        List<Integer> idList = new ArrayList<>();
        idList.add(id);
        goodsService.addStorage(idList);
    }

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void downGoods(String id) {
        log.info("downGoods == {}", id);
        //根据第三方平台id，获取商品信息。
        List<String> skuIdList = new ArrayList<>();
        List<GoodsSku> skuList = new ArrayList<>();
        skuList = goodsSkuService.getGoodsSkuListByGoodsId(id);
        if (CollectionUtil.isNotEmpty(skuList)) {
            skuIdList = skuList.stream().map(GoodsSku::getId).map(String::valueOf).collect(Collectors.toList());
        }
        //下架商品
        Goods goods = new Goods();
        goods.setId(id);
        goods.setMarketEnable(GoodsMarketEnum.DOWN.name());
        goods.setAuthFlag(GoodsAuthEnum.TOBEAUDITED.name());
        goodsService.updateById(goods);
        log.info("下架商品sku skuList == {}", JSONObject.toJSONString(skuList));
        if (CollectionUtil.isNotEmpty(skuList)) {
            for (GoodsSku goodsSku : skuList) {
                goodsSku.setMarketEnable(GoodsMarketEnum.DOWN.name());
                goodsSku.setAuthFlag(GoodsAuthEnum.TOBEAUDITED.name());
            }
            goodsSkuService.updateBatchById(skuList);
        }
        //删除缓存 + 索引
        List<String> goodsCacheKeys = new ArrayList<>();
        List<String> goodsSkuCacheKeys = new ArrayList<>();

        goodsCacheKeys.add(CachePrefix.GOODS.getPrefix() + id);
        // 遍历商品sku缓存key
        skuIdList.forEach(skuId -> goodsSkuCacheKeys.add(CachePrefix.GOODS_SKU.getPrefix() + skuId));
        // 发送删除商品信息
        log.info("开始发送删除商品信息");
        applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent.builder().source("删除商品").exchange(amqpExchangeProperties.getGoods()).routingKey(GoodsRoutingKey.GOODS_DELETE).message(id).build());
        log.info("结束发送删除商品信息");
        // 清除缓存
        cache.multiDel(goodsCacheKeys);
        cache.multiDel(goodsSkuCacheKeys);
    }


    @ApiOperation(value = "更新是否全返商品")
    @Override
    public boolean updateResultGoods(List<String> goodsId, Boolean isResultGoods) {
        return goodsIntegrationService.updateResultGoods(goodsId,isResultGoods);
    }

    @Override
    public void cleanGoodsCache(List<String> goodsIds) {
        goodsService.cleanGoodsCache(goodsIds);
    }

    @Override
    public boolean createGoods(BoxMhgoodsVO boxMhgoodsVO) {
        return goodsService.createGoods(boxMhgoodsVO);
    }

    @Override
    public boolean removeGoods(List<String> goodsIds, String storeId) {
        return goodsIntegrationService.deleteGoodsV2(goodsIds, storeId);
    }

    @Override
    public boolean addGoods(String id) {
        GoodsSearchParams goodsSearchParams = new GoodsSearchParams();
        goodsSearchParams.setCursor(Integer.parseInt(id) - 1);
        goodsSearchParams.setPageSize(1);
        return goodsService.addGoods(goodsSearchParams);
    }


    /**
     * 搜索es商品
     * @param goodsId goodsId
     * @return
     */
    @Override
    public Page<EsGoodsIndex> searchEsByGoodsId(String goodsId) {
        EsGoodsSearchDTO goodsSearchParams = new EsGoodsSearchDTO();
        goodsSearchParams.setGoodsId(goodsId);
        PageVO pageVO = new PageVO();
        return goodsSearchService.searchGoodsByPage(goodsSearchParams, pageVO, EsGoodsIndex.class,true);
    }

    @Override
    public long getGoodsCountByStoreIds(List<String> storeIds, String marketEnable) {
        return goodsService.getGoodsCountByStoreIds(storeIds, marketEnable);
    }

    @Override
    public long getCurrentMonthGoodsCountByStoreIds(List<String> storeIds) {
        return goodsService.getCurrentMonthGoodsCountByStoreIds(storeIds);
    }

    @Override
    public long getGoodsCountByParams(UrbanStationSearchParams params) {
        return goodsService.getGoodsCountByParams(params.getStoreIds(), params.getStartTime(), params.getEndTime());
    }

    @Override
    public void execute() {

        try {
            reSendMessage();
        } catch (Exception e) {
            log.error("海关与保税仓订单重发失败 ==  ", e);
        }
    }


    /**
     * 重发海关与保税仓数据
     */
    @SneakyThrows
    private void reSendMessage() {
        OrderSearchParams orderSearchParams = new OrderSearchParams();
        orderSearchParams.setIsErrorFree(true);
        List<Order> orderList = orderClient.queryListByParams(orderSearchParams);
        if (CollectionUtil.isEmpty(orderList)) {
            return;
        }
        List<String> orderSnList = orderList.stream().map(Order::getSn).toList();
        LambdaQueryWrapper<FreeOrderLog> freeOrderLogLambdaQueryWrapper = new LambdaQueryWrapper<>();
        freeOrderLogLambdaQueryWrapper.in(FreeOrderLog::getOrderSn, orderSnList);
        freeOrderLogLambdaQueryWrapper.eq(FreeOrderLog::getStatusType, CommonConstant.STATUS_TYPE_02);
        List<FreeOrderLog> orderLogList = freeOrderLogService.list(freeOrderLogLambdaQueryWrapper);

        for (FreeOrderLog freeOrderLog : orderLogList) {
            if (Objects.equals(freeOrderLog.getPlatformType(), CommonConstant.PLATFORM_TYPE_01)) {
                this.reSendFreeMessage(freeOrderLog);
            }
            if (Objects.equals(freeOrderLog.getPlatformType(), CommonConstant.PLATFORM_TYPE_02)) {
                this.reSendCustomsMessage(freeOrderLog);
            }
        }


    }

    @SneakyThrows
    private void reSendCustomsMessage(FreeOrderLog freeOrderLog) {
        //上报海关
        ObjectMapper mapper = new ObjectMapper();
        String sendMessage = freeOrderLog.getSendMessage();
        UploadCEBMessageRequest uploadCEBMessageRequest = mapper.readValue(JSONObject.toJSONString(sendMessage), UploadCEBMessageRequest.class);
        JSONObject uploadRes = freeWarehouse.sendCustomsRequest(FreeWarehouseConstant.UPLOAD_MESSAGE, uploadCEBMessageRequest);
        log.info("uploadRes == {}", JSONObject.toJSONString(uploadRes));

        //接收海关回应
        JSONObject receiveJson = freeWarehouse.sendCustomsRequest(FreeWarehouseConstant.RECEIVE_MESSAGE, null);
        log.info("receiveJson == {}", receiveJson);
        //成功
        if (receiveJson.getInteger("code") >= 0) {
            log.info("上传海关 成功 == {}", freeOrderLog.getOrderSn());
            Order order = new Order();
            order.setSn(freeOrderLog.getOrderSn());
            //设置成空
            order.setCustomsErrorMessage(StringPool.NULL);
            orderClient.update(order);
            //将保税仓的数据设置成重试成功
            freeOrderLog.setStatusType(CommonConstant.STATUS_TYPE_01);
            freeOrderLogService.updateById(freeOrderLog);
        } else {
            freeOrderLog.setReturnMessage(receiveJson.toJSONString());
            freeOrderLogService.updateById(freeOrderLog);

            String returnInfo = receiveJson.getString("returnInfo");
            Order order = new Order();
            order.setSn(freeOrderLog.getOrderSn());
            order.setCustomsErrorMessage(returnInfo);
            orderClient.update(order);
        }
    }

    /**
     * 重发保税仓数据
     * @param freeOrderLog 失败发送日志
     */
    @SneakyThrows
    private void reSendFreeMessage(FreeOrderLog freeOrderLog) {
        ObjectMapper mapper = new ObjectMapper();
        String sendMessage = freeOrderLog.getSendMessage();
        ShopSalesOrderReq shopSalesOrderReq = mapper.readValue(JSONObject.toJSONString(sendMessage), ShopSalesOrderReq.class);
        JSONObject warehouseJson = freeWarehouse.sendHttpRequest(FreeWarehouseConstant.SHOP_SALES_ORDER_CREATE, shopSalesOrderReq);
        if (warehouseJson.getInteger("resultCode") == 1) {
            log.info("上传保税仓 成功 == {}", freeOrderLog.getOrderSn());
            ShopSalesOrderRes res = mapper.readValue(warehouseJson.getJSONObject("resultData").toJSONString(), ShopSalesOrderRes.class);
            log.info("ShopSalesOrderRes == {} ", JSONObject.toJSONString(res));
            Order order = new Order();
            order.setTrackingNo(res.getTrackingNo());
            order.setSn(freeOrderLog.getOrderSn());
            //设置成空
            order.setFreeErrorMessage(StringPool.NULL);
            orderClient.update(order);
            //将保税仓的数据设置成重试成功
            freeOrderLog.setStatusType(CommonConstant.STATUS_TYPE_01);
            freeOrderLogService.updateById(freeOrderLog);
        } else {
            Order order = new Order();
            order.setSn(freeOrderLog.getOrderSn());
            order.setFreeErrorMessage(warehouseJson.getString("resultContent"));
            orderClient.update(order);
        }
        log.info("warehouseJson == {}", JSONObject.toJSONString(warehouseJson));
    }

    /**
     * 获取所有，免税仓的订单, 去做状态查询，并同步数据
     */
    private void syncOrderStatus() {
        long startTime = System.currentTimeMillis();
        log.info("开始同步订单状态 == {}", startTime);
        //获取所有，免税仓的订单
        OrderSearchParams orderSearchParams = new OrderSearchParams();
        orderSearchParams.setSyncOrder(true);
        List<Order> orderList = orderClient.queryListByParams(orderSearchParams);
        log.info("syncOrderStatus orderList = {}", JSONObject.toJSONString(orderList));
        if (CollectionUtil.isEmpty(orderList)) {
            return;
        }
        //请求，查询这些订单是否出库
        List<JSONObject> reqJsonArr = new ArrayList<>();
        for (Order order : orderList) {
            log.info("order == {}", JSONObject.toJSONString(order));
            if (order == null) {
                continue;
            }
            JSONObject reqJson = freeWarehouse.generateQueryJson("orderNo", order.getOutTradeNo());
            reqJsonArr.add(reqJson);
        }
        log.info("reqJsonArr == {}", JSONObject.toJSONString(reqJsonArr));
        if (CollectionUtil.isEmpty(reqJsonArr)) {
            return;
        }
        for (JSONObject req : reqJsonArr) {
            JSONObject jsonObject = freeWarehouse.sendHttpRequest(FreeWarehouseConstant.ORDER_QUERY_ONE, req);
            log.info("jsonObject == {}", jsonObject.toJSONString());
            if (jsonObject.getInteger("resultCode") == 1) {
                JSONObject resultData = jsonObject.getJSONObject("resultData");
                String expressName = resultData.getString("expressName");
                String expressCode = resultData.getString("expressCode");
                String parcelCode = resultData.getString("parcelCode");
                String outTradeNo = resultData.getString("orderNo");
                String orderStatus = resultData.getString("orderStatus");
                log.info("expressName == {}, expressCode == {}, parcelCode == {}, outTradeNo == {}, orderStatus == {}", expressName, expressCode, parcelCode, outTradeNo, orderStatus);
                //订单状态已出仓库，或后面的订单状态就，将订单修改为已发货
                //不为空  && 不等于新创建订单 &&  不能不等于入库 &&  不等于称重
                Order order = null;
                for (Order orderFor : orderList) {
                    if (StringUtils.isNotEmpty(orderFor.getOutTradeNo()) && orderFor.getOutTradeNo().equals(outTradeNo)) {
                        order = orderFor;
                    }
                }
                boolean snNotNull = order != null && StringUtils.isNotEmpty(order.getSn());
                log.info("snNotNull = {}", snNotNull);
                List<OrderFreeStatusLog> orderFreeStatusLogList = orderFreeStatusLogClient.getBySnAndOrderStatus(outTradeNo, orderStatus);
                log.info("orderFreeStatusLogList = {}, orderNo = {}, orderStatus ={}",
                        JSONObject.toJSONString(orderFreeStatusLogList), outTradeNo, orderStatus);
                if (snNotNull && CollectionUtil.isEmpty(orderFreeStatusLogList)) {
                    OrderFreeStatusLog orderFreeStatusLog = new OrderFreeStatusLog();
                    orderFreeStatusLog.setOrderStatus(orderStatus);
                    orderFreeStatusLog.setOrderSn(order.getSn());
                    orderFreeStatusLog.setOutTradeNo(outTradeNo);
                    orderFreeStatusLogClient.save(orderFreeStatusLog);
                }
                //保税仓出仓库  我们去发货
                boolean orderStatusExpression = StringUtils.isNotEmpty(orderStatus) && orderStatus.equals(CommonConstant.ORDER_STATUS_OUTBOUND);
                //系统订单  => 处于待发货
                boolean undelivered = OrderStatusEnum.UNDELIVERED.name().equals(order != null ? order.getOrderStatus() : "");
                //订单状态等于代发货, 且保税仓出库 = 系统需要去发货
                if (StringUtils.isNotEmpty(expressCode) && StringUtils.isNotEmpty(expressName) && orderStatusExpression && undelivered && snNotNull) {
                    Logistics logistics = logisticsClient.getByName(expressName);
                    if (logistics == null) {
                        logistics = new Logistics();
                        logistics.setCode(expressCode);
                        logistics.setDisabled(SwitchEnum.OPEN.name());
                        logistics.setName(expressName);
                        logistics.setStandBy("true");
                        String id = logisticsClient.save(logistics);
                        logistics.setId(id);
                    }
                    //订单发货
                    orderClient.delivery(order.getSn(), parcelCode, logistics.getId());
                }
                boolean delivered = OrderStatusEnum.DELIVERED.name().equals(order != null ? order.getOrderStatus() : "");
                //保税仓状态  * 拒签 Rejected * 丢失 Lost * 销毁 Destory * 签收 Signed * 退单 Return
                //我们去变更成已完成
                boolean orderStatusCompleted = StringUtils.isNotEmpty(orderStatus) &&
                        (orderStatus.equals(CommonConstant.ORDER_STATUS_REJECTED) || orderStatus.equals(CommonConstant.ORDER_STATUS_LOST) ||
                                orderStatus.equals(CommonConstant.ORDER_STATUS_DESTORY) || orderStatus.equals(CommonConstant.ORDER_STATUS_SIGNED) ||
                                orderStatus.equals(CommonConstant.ORDER_STATUS_RETURN));
                if (delivered && orderStatusCompleted && snNotNull) {
                    //订单完成
                    orderClient.complete(order.getSn());
                }
                //保税仓主动，取消订单。我们也进行订单取消
                log.info("order.getOrderStatus() = {}", order.getOrderStatus());
                if (orderStatus.equals(CommonConstant.ORDER_STATUS_CANCEL) && !OrderStatusEnum.CANCELLED.name().equals(order.getOrderStatus()) && snNotNull) {
                    log.info("进入保税仓取消操作");
                    orderClient.cancel(order.getSn(), CommonConstant.CANCEL_REMARK);
                }
            }
        }
        log.info("结束同步订单状态 == {}", System.currentTimeMillis() - startTime);
    }


    @Override
    public JSONObject sendHttpRequest(InterceptReq interceptReq) {
        log.info("sendHttpRequest1 = {}", JSONObject.toJSONString(interceptReq));
        return freeWarehouse.sendHttpRequest(interceptReq.getApiUrl(), interceptReq);
    }

    /**
     * 获取所有，免税仓的订单, 去做状态查询，并同步数据
     */
    @Override
    public void minuteExecute() {
        RLock lock = null;
        try {
            lock = redisson.getLock("minuteExecute");
            lock.tryLock(2000, 3000, TimeUnit.MILLISECONDS);
            //获取所有，免税仓的订单, 去做状态查询，并同步数据
            syncOrderStatus();
        } catch (Exception e) {
            log.error("error == {}", e.getMessage());
            e.printStackTrace();
        } finally {
            if (lock != null) {
                lock.unlock();
                log.info("强制释放锁");
            }
        }
    }
}
